import re
from loguru import logger
# from conf import conf
from app.core.conf import ST
from app.models import Station,Dev


class Filter:

    __slots__ = ('ocr_raw_list','ocr_filter_list','ocr_temp_humi_list','ocr_base_list','dev')


    def __init__(self,ocr_raw_list,dev:Dev) -> None:
        self.ocr_raw_list = ocr_raw_list # 原始的ocr数组
        self.ocr_filter_list = [] # 过滤进行中的ocr数组
        self.ocr_temp_humi_list = [] # 温湿度的ocr数组
        self.ocr_base_list = []
        self.dev = dev


    def filter_temp_humi(self):
        """过滤杂七杂八的字符，剩下可能是温湿度的字符串,顺序不能乱
        """
        # 初始化一下要进行过滤字符串
        self.ocr_filter_list = self.ocr_raw_list
        self.filter_chinese_by_count(count=2)
        self.filter_only_2_chinese()
        self.filter_digit_by_count_range(min=2, max=3)
        self.filter_character_by_count(count=0)
        self.filter_by_probability(probability = 0.89)
        self.filter_keyword_drop()
        if self.dev.cv_type=="red_temp_blue_humi_2":
            self.filter_keyword_drop(['25'])

        # 将过滤完成的字符串进行存储起来
        self.ocr_temp_humi_list = self.ocr_filter_list
        
    def filter_base(self):
        """过滤出来，用来作为基准，判断温湿度的文字
        """
        self.ocr_filter_list = self.ocr_raw_list
        self.filter_keyword_save()
        logger.debug(self.ocr_filter_list);
        self.filter_only_2()
        logger.debug(self.ocr_filter_list);
        self.ocr_base_list = self.ocr_filter_list


    def filter_pure_chinese(self):
        self.ocr_filter_list = [s for s in self.ocr_raw_list if  Filter.is_all_chinese(s.get('t')) ]
        self.ocr_filter_list = [s for s in self.ocr_filter_list if len(s.get('t')) > 1 and len(s.get('t')) < 5 and not len(s.get('t'))==3]
        

    def log_filter_ocr(self):
        for ocr in self.ocr_filter_list:
            logger.debug(ocr)


    def log_filter_ocr_yellow(self,ocr_list = None):
        if not ocr_list:
            ocr_list = self.ocr_filter_list

        for ocr in ocr_list:
            logger.warning(ocr)

    # def is_all_chinese(self,s):
    #     pattern = re.compile(r'^[\u4e00-\u9fa5]+$')
    #     return bool(pattern.match(s))

    def filter_character_by_count(self,count=0):
        """过滤掉字符串中英文字母数量大于0的字符串

        Args:
            count (int, optional): _description_. Defaults to 0.
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if not Filter.count_letters(s.get('t')) > count]

    def filter_by_probability(self,probability = 0.98):
        """根据识别的准确率过滤字符串
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if s.get('p') > probability]


    def filter_chinese_by_count(self,count = 2):
        """过滤掉字符串中汉字长度大于2的字符串，为什么是2，因为有的识别成  "温度：20.0", 所以把阈值调到2
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if not Filter.count_chinese(s.get('t')) > count]

    def filter_only_2_chinese(self):
        """过滤掉只有两个汉字的字符串
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if not ( Filter.count_chinese(s.get('t')) == 2 and len(s.get('t'))==2 )]

    def filter_only_2(self):
        """过滤掉只有两个字符的字符串
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if  len(s.get('t'))==2]



    @staticmethod
    def count_chinese(s):
        pattern = re.compile(r'[\u4e00-\u9fa5]')
        return len(pattern.findall(s))


    def filter_keyword_drop(self,keyword_list=None):
        if keyword_list is None:
            self.ocr_filter_list = [s for s in self.ocr_filter_list if Filter.keyword_drop(s.get('t'))]
        else:
            self.ocr_filter_list = [s for s in self.ocr_filter_list if s.get('t') not in keyword_list]





    @staticmethod
    def keyword_drop(text):
        drop_flag_list = [ keyword in text for keyword in ST.ocr_keyword_drop]
        if any(drop_flag_list): # 至少有一个为真,就返回真值
            return None
        return text

    def filter_keyword_save(self):
        self.ocr_filter_list = [s for s in self.ocr_filter_list if Filter.keyword_save(s.get('t'))]

    @staticmethod
    def keyword_save(text):
        drop_flag_list = [ keyword in text for keyword in ST.ocr_keyword_save]
        if any(drop_flag_list): # 至少有一个为真,就返回真值
            return text
        return None
 

    @staticmethod
    def count_letters(s):
        pattern = re.compile(r'[a-zA-Z]')
        return len(pattern.findall(s))

    def filter_digit_by_count_range(self, min=2, max=3):
        """过滤掉字符串中数字数量大于3或者小于2的字符串，也就是只保留字符串中数字数量等于2或3的字符串。

        Args:
            min (int, optional): _description_. Defaults to 2.
            max (int, optional): _description_. Defaults to 3.
        """
        self.ocr_filter_list = [s for s in self.ocr_filter_list if not Filter.count_digit(s.get('t')) > max]
        self.ocr_filter_list = [s for s in self.ocr_filter_list if not Filter.count_digit(s.get('t')) < min ]


    def count_decimal_points(self,s):
        pattern = re.compile(r'\.')
        return len(pattern.findall(s))

    @staticmethod
    def count_digit(s): 
        num=0
        for ch in s:
            if ch.isdigit() :
                num+=1
        return num

    @staticmethod
    def get_pure_digit(text):
        """_提取识别出来中的温度,纯数字部分_

        Returns:
            _type_: _description_
        """
        if text is None:
            return None
        res = re.search(r'-?\d+\.?\d*',text)
        if res:
            return res.group()
        else:
            return None 

    @staticmethod
    def is_all_chinese(word):  
        """  
        判断一个字符串是否全部由汉字组成  
        """  
        for ch in word:
            if not('\u4e00' <= ch <= '\u9fef') and not ('\u3400' <= ch <= '\u4db5') \
                    and not ('\u20000' <= ch <= '\u2a6d6') and not ('\u2a700' <= ch <= '\u2b734')\
                    and not ('\u2b740' <= ch <= '\u2b81d') and not ('\u2b820' <= ch <= '\u2cea1')\
                    and not ('\u2ceb0' <= ch <= '\u2ebe0') and not ('\u2f00' <= ch <= '\u2fd5')\
                    and not ('\u2e80' <= ch <= '\u2ef3') and not ('\uf900' <= ch <= '\ufad9')\
                    and not ('\u2f800' <= ch <= '\u2fa1d') and not ('\ue815' <= ch <= '\ue86f')\
                    and not ('\ue400' <= ch <= '\ue5e8') and not ('\ue600' <= ch <= '\ue6cf')\
                    and not ('\u31c0' <= ch <= '\u31e3') and not ('\u2ff0' <= ch <= '\u2ffb')\
                    and not ('\u3105' <= ch <= '\u312f') and not ('\u31a0' <= ch <= '\u31ba'):
                return False
                break
        return True